const fs = require('fs');
const path = require('path');
const YAML = require('yaml');
const yargs = require('yargs');

module.exports = function getOptions() {
  let cfg = {};
  for (const fn of [
    'messageformat.rc.js',
    'messageformat.rc.json',
    'messageformat.rc.yaml',
    'messageformat.rc.yml'
  ]) {
    try {
      const cfgPath = path.resolve(fn);
      if (fn.endsWith('.js')) {
        cfg = require(cfgPath);
      } else {
        const src = fs.readFileSync(cfgPath, 'utf8');
        cfg = YAML.parse(src);
      }
      break;
    } catch {
      /* ignore errors */
    }
  }
  const usage = `$0 [input, ...] [options]

Parses input JSON, YAML, and .properties files of MessageFormat strings into
an ES module of corresponding hierarchical functions. Input directories are
recursively scanned for all files matching the supported extensions.

Configuration may also be set under the package.json "messageformat" key or
messageformat.rc.{js,json,yaml}.`;

  return yargs
    .scriptName('messageformat')
    .pkgConf('messageformat')
    .config(cfg)
    .options({
      delimiters: {
        alias: 'd',
        array: true,
        default: ['._/\\']
      },
      'eslint-disable': {
        boolean: true,
        hidden: true
      },
      extensions: {
        alias: 'e',
        array: true,
        default: ['.json', '.properties', '.yaml', '.yml']
      },
      locale: {
        alias: 'l',
        array: true,
        desc: `The locale(s) to include; if multiple, selected by matching message key. If not set, path keys matching any locale code will set the active locale, starting with a default 'en' locale.`
      },
      options: {
        desc: `Options to pass to the MessageFormat constructor via its second argument. Use dot-notation to set values, e.g. --options.currency=EUR. For custom formatters, string values will be require()'d based on the current working directory.`
      },
      outfile: {
        alias: 'o',
        default: '-',
        desc: 'Write output to the specified file. If undefined or "-", prints to stdout.',
        string: true
      },
      simplify: {
        alias: 's',
        boolean: true
      }
    })
    .coerce({
      delimiters(delim) {
        const str = delim.join('').replace(/[-\]\\]/g, '\\$&');
        return new RegExp(`[${str}]`);
      },
      extensions(ext) {
        return ext.map(x => x.trim().replace(/^([^.]*\.)?/, '.'));
      },
      locale(locales) {
        if (!locales) return '*';
        const ls = locales.reduce((ls, lc) => ls.concat(lc.split(/[ ,]+/)), []);
        return ls.length > 0 ? ls : '*';
      },
      options(opt = {}) {
        if (opt.customFormatters) {
          const cf = opt.customFormatters;
          if (typeof cf === 'string') {
            const cp = cf[0] === '.' ? path.resolve(cf) : cf;
            opt.customFormatters = require(cp);
          } else {
            for (const [name, fn] of Object.entries(cf)) {
              if (typeof fn === 'string') {
                const fp = fn[0] === '.' ? path.resolve(fn) : fn;
                cf[name] = require(fp);
              }
            }
          }
        }
        return opt;
      },
      _(input) {
        if (input.length === 0) {
          throw new Error('At least one input file or directory is required.');
        }
        return input.map(fn => path.resolve(fn));
      }
    })
    .usage(usage)
    .help()
    .version()
    .parse();
};
